import { Context, Schema, h } from 'koishi'

import {} from 'koishi-plugin-adapter-onebot';

export const inject = {
  required: ["http"]
}

export const name = 'gen-shouban-img'

export interface Config {
  makuoBackendAuthToken: string
  maxRetryTimes: number
  retryIntervalMs: number
  eachChannelCooldownMs: number
  cooldownWhitelist: Array<string>
}

export const Config: Schema<Config> = Schema.intersect([
  Schema.object({
    makuoBackendAuthToken: Schema.string()
      .default('在这里填入你的token')
      .description('去平台注册账号拿token~ 在这里： https://api.makuo.cc/auth/register'),
    maxRetryTimes: Schema.number()
      .default(5)
      .min(1).max(10).step(1)
      .description("最大重试次数， 默认5"),
    retryIntervalMs: Schema.number()
      .default(10000)
      .min(5000).max(600000).step(1000)
      .description("重试时间间隔， 默认10s"),
    eachChannelCooldownMs: Schema.number()
      .default(300000)
      .min(5000).max(600000).step(1000)
      .description("每个群独立的cd， 默认300s"),
    cooldownWhitelist: Schema.array(String)
      .default(['1830540513'])
      .description('cd白名单')
  })
])

export function apply(ctx: Context, config: Config) {
  const cooldownMap = new Map<string, number>();

  ctx.command('生成手办')
    .alias('ags')
    .alias('awa_gen_shouban')
    .action(async ({ session }) => {
      // --- 新增冷却时间检查逻辑 ---
      if (session.channelId) {
        const lastRequestTime = cooldownMap.get(session.channelId);
        const currentTime = Date.now();
        const cooldown = config.eachChannelCooldownMs;

        if ( !config.cooldownWhitelist.includes(session.userId) && lastRequestTime && (currentTime - lastRequestTime < cooldown)) {
          // 如果不是白名单用户 而且 cd没转好的话
          // const remainingTime = Math.ceil((cooldown - (currentTime - lastRequestTime)) / 1000);
          const remainingTime = ((cooldown - (currentTime - lastRequestTime)) / 1000).toFixed(3);
          const cooldownTipMsg = `cd中，请稍后再试。此频道剩余冷却时间：${remainingTime}秒`;
          ctx.logger.info(cooldownTipMsg);
          await session.send(`${h.quote(session.messageId)}${cooldownTipMsg}`);
          if ( session.onebot ){
            await session.onebot._request(
              "set_group_reaction",
              {
                "group_id": session.guildId,
                "message_id": session.event.message.id,
                "code": "128164",
                "is_add": true
              }
            )
            await session.onebot._request(
              "set_msg_emoji_like",
              {
                "message_id": session.event.message.id,
                "emoji_id": "128164",
              }
            )
          }
          // cd 中，return掉
          return;
        }
      }

      if (session.channelId) {
        cooldownMap.set(session.channelId, Date.now());
      }

      let waitTipMsgIdList;

      try {
        let imageUrl: string | undefined;

        if (session.quote) {
          const elements = h.parse(session.quote.content);
          for (const element of elements) {
            if (element.type === 'img') {
              imageUrl = element.attrs.src;
              break;
            }
          }
        }

        if (!imageUrl) {
          await session.send(`${h.quote(session.messageId)}请回复一条带有图片的消息来生成手办。`);
          return;
        }

        ctx.logger.info(`这次用来生成手办的url是: ${imageUrl}`);
        waitTipMsgIdList = await session.send(`${h.quote(session.messageId)}正在生成手办中，等待后端响应...`);

        // 核心修改部分
        const apiUrl = `https://api.makuo.cc/api/get.img.figure`;
        const params = { url: imageUrl };
        const headers = { 'Authorization': config.makuoBackendAuthToken };

        let response;
        let allErrMsg = '';

        for (let i = 0; i < config.maxRetryTimes; i++) {
          try {
            response = await ctx.http.get(apiUrl, { params, headers });
            
            if (response.code === 200) {
              break;
            }
          } catch (err) {
            const thisTimeErrMsg = `第${i}次err.message = ${err.message}. err.stack = ${err.stack}\n`;
            allErrMsg += thisTimeErrMsg;
            ctx.logger.info(thisTimeErrMsg);
            ctx.logger.info(`将在${config.retryIntervalMs}ms后进行第 ${i + 1}/${config.maxRetryTimes} 次重试...`);
          }
          if (i < config.maxRetryTimes - 1) {
            await new Promise(resolve => setTimeout(resolve, config.retryIntervalMs));
          }
        }

        if (response && response.code === 200 && response.data?.figure_url) {
          await session.send(`${h.quote(session.messageId)}${h.image(response.data.figure_url)}`);
        } else {
          const resMsg = response ? JSON.stringify(response) : `未知错误，无响应体。所有的错误: ${allErrMsg}`;
          const errMsg = `API请求在所有重试后仍失败，请稍后再试。图片链接:${imageUrl}, resMsg: ${resMsg}`;
          ctx.logger.error(errMsg);
          throw new Error(errMsg);
        }

      } catch (err) {
        const errMsg = `生成手办时发生未知错误。err = ${err.message}`;
        ctx.logger.error(errMsg);
        await session.send(`${h.quote(session.messageId)} ${errMsg}`);
      } finally {
        if (waitTipMsgIdList) {
          await session.bot.deleteMessage(session.messageId, waitTipMsgIdList[0]);
        }
      }
    });
}